#include <rtthread.h>
#include "modbus.h"
#include <stdio.h>
#include <string.h>

static void read_test_thread(void *param)
{
    uint16_t tab_reg[64] = {0};
    modbus_t *ctx;
    int num = 0;
    int regs;
    int i;
    int runcnt = 1000;

    ctx = (modbus_t *)param;

    while (runcnt--)
    {
        memset(tab_reg, 0, 64 * 2);
        regs = modbus_read_registers(ctx, 0, 20, tab_reg);
        num++;

        if (regs > 0)
        {
            printf("----------r-----------------r--------------\n");
            printf("[%4d][read num = %d]", num, regs);
            for (i = 0; i < 20; i++)
            {
                printf("<%#x>", tab_reg[i]);
            }
            printf("\n");
        }

        printf("------x------x------x------x------x--------\n");
        rt_thread_mdelay(1000);
    }
    //7-关闭modbus端口
    modbus_close(ctx);

    //8-释放modbus资源
    modbus_free(ctx);
}

static void write_test_thread(void *param)
{
    uint16_t tab_reg[64];
    modbus_t *ctx;
    int num = 0;
    int regs;
    int i;
    int runcnt = 1000;

    ctx = (modbus_t *)param;
    for (i = 0; i < 64; i++)
        tab_reg[i] = 0x1234;

    while (runcnt--)
    {
        regs = modbus_write_registers(ctx, 0, 64, tab_reg);
        num++;

        if (regs > 0)
        {
            printf("------------w-----------------w------------\n");
            printf("[%4d][write num%d]\n", num, regs);
        }

        printf("------x------x------x------x------x--------\n");
        rt_thread_mdelay(1000);
    }
    //7-关闭modbus端口
    modbus_close(ctx);

    //8-释放modbus资源
    modbus_free(ctx);
}

static int _resize_buf(const char *dev)
{
    int fd;

    fd = open(dev, 0);
    ioctl(fd, TIOCSOBUFSZ, (void *)300);
    ioctl(fd, TIOCSIBUFSZ, (void *)300);
    close(fd);

    return 0;
}

static modbus_t *modbus_init(const char *dev)
{
    modbus_t *ctx;

    ctx = modbus_new_rtu(dev, 115200, 'N', 8, 1);
    if (ctx)
    {
        if (modbus_connect(ctx) != 0)
        {
            modbus_free(ctx);
            printf("modbus connect fail\n");
            return RT_NULL;
        }

        _resize_buf(dev);

        modbus_set_slave(ctx, 2);
        modbus_set_response_timeout(ctx, 0, 1000000);
    }

    return ctx;
}

static int mbrtu(int argc, char **argv)
{
    rt_thread_t tid = 0;
    modbus_t *ctx;
    int mode = 0;

    if (argc < 3)
    {
        printf("mbrtu :dev/uart1 r  --  read registers\n");
        printf("mbrtu :dev/uart1 w  --  write registers\n");
        return -1;
    }

    ctx = modbus_init(argv[1]);
    if (!ctx)
    {
        return -1;
    }

    if (strcmp(argv[2], "w") == 0)
        mode = 1;

    switch (mode)
    {
    case 0:
    {
        tid = rt_thread_create("rtu-r", read_test_thread, ctx, 2048, 12, 10);
    }
    break;
    case 1:
    {
        tid = rt_thread_create("rtu-w", write_test_thread, ctx, 2048, 12, 10);
    }
    break;
    }

    if (tid != RT_NULL)
        rt_thread_startup(tid);

    return 0;
}
MSH_CMD_EXPORT(mbrtu, modbus RTU test);
